package com.tduck.cloud.api.web.ao;

import com.tduck.cloud.account.service.OrgService;
import com.tduck.cloud.account.service.UserService;
import com.tduck.cloud.common.util.RedisUtil;
import com.tduck.cloud.form.dto.FormReportDetailDTO;
import com.tduck.cloud.form.entity.UserFormEntity;
import com.tduck.cloud.form.entity.UserFormItemEntity;
import com.tduck.cloud.form.entity.enums.FormItemTypeEnum;
import com.tduck.cloud.form.request.ExportRequest;
import com.tduck.cloud.form.service.UserFormDataService;
import com.tduck.cloud.form.service.UserFormItemService;
import com.tduck.cloud.form.service.UserFormService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("formDataAO")
@Slf4j
@RequiredArgsConstructor
public class FormDataAO {
    private final UserFormDataService userFormDataService;
    private final UserFormItemService userFormItemService;
    private final UserFormService userFormService;
    private final UserService userService;
    private final OrgService orgService;
    private final RedisUtil redisUtil;
    private final FormReportAO formReportAO;

    public void exportAllData(ExportRequest.FormData exportRequest, HttpServletRequest request, HttpServletResponse response) {
        log.debug("exportAllData start .....");
        String formKey = exportRequest.getFormKey();
        UserFormEntity userFormEntity = userFormService.query().eq("form_key", formKey).one();
        List<UserFormItemEntity> itemEntityList = userFormItemService.query().eq("form_key", formKey).eq("type", FormItemTypeEnum.MATRIX_SELECT).orderByAsc("sort").list();
        List<FormReportDetailDTO> formReportDetails = formReportAO.expandData(formKey).stream().filter(f -> f.getFormItemType().equals(FormItemTypeEnum.MATRIX_SELECT)).collect(Collectors.toList());
        Map<Long, List<FormReportDetailDTO>> subMap = formReportDetails.stream().collect(Collectors.groupingBy(FormReportDetailDTO::getEvaluator));
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet();
        Row titleRow = sheet.createRow(0);
        Map<String, Integer> indexMap = new HashMap<>(itemEntityList.size());
        titleRow.createCell(0).setCellValue("被评价者");
        for (int i = 0; i < itemEntityList.size(); i++) {
            UserFormItemEntity userFormItem = itemEntityList.get(i);
            Cell cell = titleRow.createCell(i + 1);
            cell.setCellValue(userFormItem.getTextLabel());
            indexMap.put(userFormItem.getFormItemId(), i + 1);
        }
        titleRow.createCell(itemEntityList.size() + 1).setCellValue("评价人");
        titleRow.createCell(itemEntityList.size() + 2).setCellValue("总分");
        titleRow.createCell(itemEntityList.size() + 3).setCellValue("平均分");
        int j = 1;
        for (Map.Entry<Long, List<FormReportDetailDTO>> entry : subMap.entrySet()) {
            List<FormReportDetailDTO> subData = entry.getValue();
            Map<Long, List<FormReportDetailDTO>> detailMapByEvaluated = subData.stream().collect(Collectors.groupingBy(FormReportDetailDTO::getEvaluated));
            for (Map.Entry<Long, List<FormReportDetailDTO>> subEntry : detailMapByEvaluated.entrySet()) {
                Row row = sheet.createRow(j++);
                List<FormReportDetailDTO> subList = subEntry.getValue();
                for (int i = 0; i < subList.size(); i++) {
                    FormReportDetailDTO formReportDetail = subList.get(i);
                    Cell evaluatedRow = row.createCell(0);
                    evaluatedRow.setCellValue(formReportDetail.getEvaluatedName());
                    Cell scoreCell = row.createCell(indexMap.get(formReportDetail.getFormItemId()));
                    scoreCell.setCellValue(formReportDetail.getScore());
                }
                Double total = subList.stream().mapToDouble(FormReportDetailDTO::getScore).sum();
                Double average = total / subList.size();
                BigDecimal bigDecimal = BigDecimal.valueOf(average);
                row.createCell(subList.size() + 1).setCellValue(subList.get(0).getEvaluatorName());
                row.createCell(subList.size() + 2).setCellValue(total);
                row.createCell(subList.size() + 3).setCellValue(bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
            }

        }
        try (OutputStream outputStream = response.getOutputStream()) {
            String fileName = "formData_" + System.currentTimeMillis() + ".xlsx";
            String userAgent = request.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                // 非IE浏览器的处理：
                fileName = new String((fileName).getBytes("UTF-8"), "ISO-8859-1");
            }
            response.reset();
            //添加响应头的跨域信息--开始
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.setContentType("application/octet-stream");
            response.addHeader("content-disposition", "attachment; filename=" + fileName);
            workbook.write(outputStream);
        } catch (Exception e) {
            log.error("导出数据失败", e);
        }
        log.debug("exportAllData end .....");
    }
}
